home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / dtr / save.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  12.4 KB  |  376 lines

  1. /*
  2.  * Copyright (c) 1990, 1991 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23.  
  24. /* $Header: /Source/Media/collab/DTR/RCS/save.c,v 1.0 92/01/06 17:52:36 drapeau Exp Locker: derek $ */
  25. /* $Log:    save.c,v $
  26.  * Revision 1.0  92/01/06  17:52:36  drapeau
  27.  * * Deleted InitPaths() since no longer necessary.
  28.  * * Modified SaveSoundFile() so that removing a file now uses the system
  29.  *   call unlink() instead of using the more awkward "system()" function.
  30.  * Also, Made a number of cosmetic changes to make code easier to read and
  31.  * to conform to programming specifications.
  32.  * 
  33.  * Revision 0.23  91/09/18  22:47:37  derek
  34.  * The following things are done:
  35.  * 1.    The Makefile is changed corresponding to the changes in collab/.
  36.  * 2.    Copyright messages included.
  37.  * 3.    Some minor bugs fixed.
  38.  * 
  39.  * Revision 0.22  91/08/21  11:34:31  derek
  40.  * The following changes are made:
  41.  * 1.    Now the duration and size of the recorded sound will be displayed
  42.  *     during recording.
  43.  * 2.    I have changed GetSelection() corresponding to the request of Tek joo
  44.  * 3.    Info Panel is added to the application.
  45.  * 4.    Fixed SizeToFitHandler() so that when no file or buffer is currently
  46.  *     loaded, it would not do anything (except giving a warning
  47.  *     notice_prompt).
  48.  * 5.    Inplemented the `Close' Menu option in the document menu.
  49.  * 6.    Fixed the bug in which after ClearAll and I press PreviewEdit,
  50.  *     the edit wont be played.
  51.  * 7.    I have made the changes corresponding to the change in OpenPanel's
  52.  *     name.  (from OpenPanel to Browse).
  53.  * 8.    Incorporated BrowseCheck to check command line arg.
  54.  * 9.    Changed most EditingStatusMessages to NoticePrompts.
  55.  * 10.    SoundFileSaveAsPopUp and EditListSaveAsPopUp are removed 
  56.  *     from the application.
  57.  * 
  58.  * Revision 0.21  91/08/16  18:10:52  derek
  59.  * 
  60.  * The following things are done:
  61.  * 1.    I have fixed an openpanel bug in my code in which I 
  62.  *     made the app return the wrong values to OpenHandler and
  63.  *     the SaveHandler.
  64.  * 2.    The flashing color of the play button has been changed from
  65.  *     Red to Green.
  66.  * 3.    Fixed a quantization bug: Buffer.play.end, when converted
  67.  *     from endingTimeInSec, should not exceed Buffer_hdr_data_size - 1.
  68.  * 
  69.  * Revision 0.20  91/08/14  16:14:13  derek
  70.  * Fixed a few saving/appending bugs.
  71.  * 
  72.  * Revision 0.19  91/08/08  11:02:24  derek
  73.  * This is a cleaner version.  I have removed lots of printf/fprintf 
  74.  * statements from it, and have also cleaned up the code using xsaber.
  75.  * This version should run substantially faster.
  76.  * 
  77.  * Revision 0.18  91/08/07  16:24:46  derek
  78.  * The Edit list part of DTR is done.  OpenPanel is also incorporated.
  79.  * 
  80.  * Revision 0.17  91/07/30  11:45:48  derek
  81.  * I have fixed the tmp file conflict bug.
  82.  * 
  83.  * Revision 0.16  91/07/26  13:18:32  derek
  84.  * Some saving bugs fixed.
  85.  * 
  86.  * Revision 0.15  91/07/23  21:25:30  derek
  87.  * This version is not ready for release.  Disk space editing is half-done:
  88.  * the application can play an infinite sound and the canvases can handle
  89.  * infinite sound files.  The app is pretty bug free too, I think.  The
  90.  * weakness is that it cannot record sond infinitely.
  91.  * 
  92.  * Revision 0.14  91/06/26  15:55:54  derek
  93.  * I have reformatted the code to conform coding specs.
  94.  * 
  95.  * Revision 0.13  91/06/25  11:40:06  derek
  96.  * I have added the new protocol items.
  97.  * 
  98.  * Revision 0.12  91/06/05  15:00:09  derek
  99.  * checking in after porting the code to collab
  100.  * 
  101.  * Revision 0.11  91/06/02  10:28:17  derek
  102.  * changes made in the save-as function
  103.  * 
  104.  * Revision 0.10  1991/04/25  01:52:26  derek
  105.  * This version is checked in on 4/24/91
  106.  * */
  107. static char rcsid[] = "$Header: /Source/Media/collab/DTR/RCS/save.c,v 1.0 92/01/06 17:52:36 drapeau Exp Locker: derek $";
  108.  
  109. #include "dtr.h"
  110. #include "dtr_ui.h"
  111.  
  112. /*
  113.  *  Verify the selected region of the waveform buffer and 
  114.  *  return its size.
  115.  */
  116. int
  117.   GetRecordedDataSize()
  118. {
  119.   int    cnt;
  120.   char    msg[256];
  121.   extern      dtr_mainWindow_objects  *dtr_mainWindow;
  122.   
  123.   EVENT("Get_Recorded_Data_Size");
  124.   
  125.   if (Buffer.hdr.data_size == 0)
  126.   {
  127.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel,
  128.             "No data in buffer.");
  129.     return (0);
  130.   }
  131.   cnt = Buffer.play.end - Buffer.play.start;
  132.   
  133.   if (cnt == 0)
  134.   {
  135.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel,
  136.             "No data in selected region.");
  137.     return (0);
  138.   }
  139.  
  140.   if (Buffer.play.start >= Buffer.hdr.data_size)            
  141.   {
  142.     sprintf(msg, "Start position (%d) beyond EOF (%d).",
  143.         Buffer.play.start, Buffer.hdr.data_size);
  144.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  145.     return (-1);
  146.   }
  147.   
  148.   if (cnt < 0)
  149.   {
  150.     sprintf(msg, "Start position (%d) beyond End position (%d).",
  151.         Buffer.play.start, Buffer.play.end);
  152.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  153.     return (-1);
  154.   }
  155.   
  156.   return (cnt);
  157. }
  158.  
  159.  
  160. int
  161.   SaveSoundFile(append, sourceFileName, destFileName)
  162. BOOL  append;
  163. char  *sourceFileName;
  164. char  *destFileName;
  165. {
  166.   char        *info = NULL;                            /*  Right now the pointer to info string is NULL... */
  167.   unsigned    Ilen = 0;                            /*  ...and set length of info string = 0.           */
  168.   int       err;
  169.   Audio_hdr      sourcetmphdr;
  170.   Audio_hdr      desttmphdr;
  171.   Audio_hdr      tmphdr;
  172.   struct stat      st;
  173.   int       bytes;
  174.   int       sourcefd;
  175.   int       destfd;
  176.   int       rtn;
  177.   int       cnt;
  178.   int       outcnt;
  179.   unsigned     char  data[1024];
  180.   int       status;
  181.   extern  dtr_mainWindow_objects  *dtr_mainWindow;
  182.   
  183.   EVENT("Save_Sound_File");
  184.   
  185.   status = FILE_NOT_OK;
  186.   err = 0;
  187.   stat(sourceFileName, &st);
  188.   if (WaveEditMode == TRUE)
  189.   {
  190.     bytes = Buffer.hdr.data_size;
  191.     
  192.     if (append)
  193.     {                                    /*  Append data to existing file.                   */
  194.       SameSoundFile = FALSE;
  195.       if ((destfd = open(Buffer.filename, O_RDWR)) < 0)
  196.       {
  197.     sprintf(msg, "Can't open '%s' (%s).",
  198.         Buffer.filename, sys_errlist[errno]);
  199.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  200.     return FILE_NOT_OK;
  201.       }
  202.       
  203.       if (!S_ISREG(st.st_mode) ||                    /*  Make sure this is already an audio file.        */
  204.       (audio_read_filehdr(destfd, &tmphdr, (char *)NULL, 0) !=
  205.        AUDIO_SUCCESS))
  206.       {
  207.     sprintf(msg, "'%s' is not a valid audio file.",
  208.         Buffer.filename, sys_errlist[errno]);
  209.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  210.     goto closerr;
  211.       }
  212.     
  213.       if ((int)lseek(destfd, st.st_size, L_SET) < 0)
  214.     goto writerr;
  215.     }
  216.     else                                /*  Create a dest file.                              */
  217.     {
  218.       destfd = open(destFileName, O_WRONLY | O_CREAT | O_TRUNC,        
  219.            0666);
  220.     
  221.       tmphdr = Buffer.hdr;                        /*  Write an audio file header first.               */
  222.       tmphdr.data_size = bytes;
  223.       if ((destfd < 0) || 
  224.       (audio_write_filehdr(destfd, &tmphdr,
  225.                    info, Ilen)
  226.        != AUDIO_SUCCESS))
  227.     goto writerr;
  228.      }
  229.   
  230.     rtn = write(destfd, (char *)&Buffer.data[Buffer.play.start], bytes);
  231.     err = (rtn != bytes);
  232.     if (append && !err)
  233.     {
  234.       if ((tmphdr.data_size != AUDIO_UNKNOWN_SIZE) &&
  235.       (audio_rewrite_filesize(destfd, 
  236.                   (tmphdr.data_size + bytes)) !=
  237.        AUDIO_SUCCESS))
  238.     err++;
  239.     }
  240.   
  241.     if (err)
  242.     {
  243.      writerr:
  244.       sprintf(msg, "Can't %s to '%s' (%s).",
  245.           (append ? "append" : "write"), destFileName,
  246.           sys_errlist[errno]);
  247.       AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  248.       goto closerr;
  249.     }
  250.     sprintf(currentSoundFile,"%s", destFileName);
  251.     if (append)                                /*  If append and in WaveEditMode...                */
  252.     {                                    /*  ...This statement is added so that if we are... */
  253.       strcpy(Buffer.filename, "");
  254.       SoundBufferReady = ReadSoundFile(TRUE);                /*  ...appending data to an existing file, the ...  */
  255.       FileReady = FALSE;                        /*  ...canvas will be displaying an updated...      */
  256.       SameSoundFile = TRUE;                        /*  ...(appended) version of the file.              */
  257.       RepaintWaveCanvas();
  258.       RepaintGlobalWaveCanvas();
  259.     }
  260.     BufferSaved = TRUE;
  261.     status = FILE_OK;
  262.    closerr:
  263.     (void) close(destfd);
  264.   }
  265.   else                                    /*  If NOT in WaveEditMode.                         */
  266.   {
  267.     if (!append)                            /*  Create a new file.                              */
  268.     {
  269.       unlink(destFileName);
  270.       sprintf(msg, "cp %s %s", SoundFileInTmp, destFileName);
  271.       system(msg);
  272.       sprintf(currentSoundFile, "%s", destFileName);
  273.       status = FILE_OK;
  274.     }
  275.     else                                /*  If appending to an existing file.               */
  276.     {
  277.       if ((sourcefd = open(sourceFileName, O_RDONLY)) < 0)        /*  Handle source file first.                       */
  278.       {
  279.     sprintf(msg, "Can't open '%s' (%s).",
  280.         sourceFileName, sys_errlist[errno]);
  281.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  282.     return FILE_NOT_OK;
  283.       }
  284.       stat(sourceFileName, &st);
  285.       if (!S_ISREG(st.st_mode) ||                    /*  Make sure the source file is already an...      */
  286.       (audio_read_filehdr(sourcefd, &sourcetmphdr,            /*  ...audio file.                                  */
  287.                   (char *)NULL, 0)
  288.        != AUDIO_SUCCESS))
  289.       {
  290.     sprintf(msg, "'%s' is not a valid audio file.",
  291.         destFileName, sys_errlist[errno]);
  292.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  293.     goto closerr2;
  294.       }
  295.       if ((destfd = open(destFileName, O_RDWR)) < 0)            /*  Now, handle dest file.                          */
  296.       {
  297.     sprintf(msg, "Can't open '%s' (%s).",
  298.         destFileName, sys_errlist[errno]);
  299.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  300.     return FILE_NOT_OK;
  301.       }
  302.     
  303.       stat(destFileName, &st);
  304.       if (!S_ISREG(st.st_mode) ||                    /*  Make sure this is already an audio file.        */
  305.       (audio_read_filehdr(destfd, &desttmphdr,
  306.                   (char *)NULL, 0)
  307.        != AUDIO_SUCCESS))
  308.       {
  309.     sprintf(msg, "'%s' is not a valid audio file.",
  310.         destFileName, sys_errlist[errno]);
  311.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  312.     goto closerr2;
  313.       }
  314.     
  315.       if ((int)lseek(destfd, st.st_size, L_SET) < 0)            /*  Seek to the end of the dest file (destFileName). */
  316.       {                                    /*  And then we will starting appending things...    */
  317.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel,        /*  ...to the end of this file.                      */
  318.                 "Error in lseek\n");
  319.       }
  320.       
  321.       outcnt = sourcetmphdr.data_size;
  322.       while(outcnt > 1024)
  323.       {
  324.     cnt = read(sourcefd, (char *)data, 1024);
  325.     rtn = write(destfd, (char *)data, cnt);
  326.     
  327.     if (rtn > 0)
  328.     {
  329.       outcnt -=rtn;
  330.     }
  331.     else
  332.       break;
  333.       }
  334.       if (outcnt > 0)
  335.       {
  336.     cnt = read(sourcefd, (char *)data, outcnt);
  337.     rtn = write(destfd, (char *)data, cnt);
  338.       }
  339.       if (!err)
  340.     if ((desttmphdr.data_size != AUDIO_UNKNOWN_SIZE) &&
  341.         (audio_rewrite_filesize(destfd,
  342.                     (sourcetmphdr.data_size +
  343.                      desttmphdr.data_size)))
  344.         != AUDIO_SUCCESS)
  345.     {
  346.       err++;
  347.     }
  348.     
  349.       if (err)
  350.       {
  351.        writerr2:
  352.     sprintf(msg, "Can't append to '%s' (%s).",
  353.         destFileName, sys_errlist[errno]);
  354.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  355.     goto closerr2;
  356.       }
  357.       sprintf(currentSoundFile, "%s", destFileName);            /*  I am hoping that in case of any error above, .. */
  358.                                     /*  ...this step will be bypassed.                  */
  359.       if (append)                            /*  This statement is added so that if we are...    */
  360.       {                                    /*  ...appending to a file, we want the canvas...   */
  361.     strcpy(Buffer.filename, "");
  362.     SoundBufferReady = ReadSoundFile(TRUE);                /*  ...to show the most updated appended version.   */
  363.     FileReady = FALSE;
  364.     SameSoundFile = TRUE;
  365.     RepaintWaveCanvas();
  366.     RepaintGlobalWaveCanvas();
  367.       }
  368.       status = FILE_OK;
  369.      closerr2:
  370.       (void) close(sourcefd);
  371.       (void) close(destfd);
  372.     }
  373.   }
  374.   return (status);
  375. }                                    /* end function SaveSoundFile */
  376.